﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Timers;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;



namespace CH_k
{
    
    public partial class FormMain : Form
    {
        Point pMouseGrid;
        Point MousePos;
        Point t;
        Point pOldElDec;
        private static System.Timers.Timer aTimer;
        
        public FormMain()
        {
            Bitmap bg = new Bitmap(10, 10);
            Graphics bgG = Graphics.FromImage(bg);
            bgG.FillRectangle(Brushes.Red, 0, 0, 1, 1);
            InitializeComponent();
            PanelMain.BackgroundImage = bg;

            aTimer = new System.Timers.Timer(100);
            aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            aTimer.Interval = 30;
            aTimer.Enabled = true;
            this.Closing+=new CancelEventHandler(Form_Closing);
        }

        private void Form_Closing(object sender, CancelEventArgs e)
        {
            System.Windows.Forms.DialogResult r = MessageBox.Show("Сохранить схему перед выходом?", "Выход", MessageBoxButtons.YesNoCancel);
            if (r == System.Windows.Forms.DialogResult.No)
            {
                Application.Exit();
            }
            else if (r == System.Windows.Forms.DialogResult.Yes)
            {
                сохранитьToolStripMenuItem_Click(sender, e);
                Application.Exit();
            }
            else 
            {
                e.Cancel = true;
            }
        }
        private void Form1_Load(object sender, EventArgs e) { }

        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            PanelMain.Invalidate();
        }
        private void PanelMain_Paint(object sender, PaintEventArgs e)
        {
            System.Drawing.Graphics bufG = e.Graphics;
            foreach (Element el in Element.seList) { el.Draw(bufG); }
            if (Element.newElement != null) Element.newElement.Draw(bufG);
            foreach (Element el in Element.seList) { el.clearRun(); };
        }

        private void PanelMain_MouseMove(object sender, MouseEventArgs e)
        {
            MousePos = e.Location;
            pMouseGrid = new Point((e.X + 5) / 10 * 10, (e.Y + 5) / 10 * 10);
            if (Element.newElement != null) Element.newElement.PosUpdate(pMouseGrid);
            if (Element.sSelEl != null)
            {
                Point t1 = new Point(pMouseGrid.X - t.X, pMouseGrid.Y - t.Y);
                Element.sSelEl.PosUpdate(t1);
            }
           
        }

        private void PanelMain_MouseClick(object sender, MouseEventArgs e)
        {
            if (Element.newElement != null)
            {
                if (Element.newElement.ElType == "ELine")
                {
                    for (int i = 0; i < Element.seList.Count; ++i )
                    {
                        Element.seList[i].TryClickInput(pMouseGrid);
                        Element.seList[i].TryClickOutput(pMouseGrid);
                    }
                }
                else
                {
                    Element.TryAdd();
                }
            }
        }

        private void PanelMain_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (Element.newElement == null)
                {
                    for (int i = 0; i < Element.seList.Count; ++i )
                    {
                        if (Element.seList[i].hover(MousePos))
                        {
                            if (MessageBox.Show("Удалить элемент и все прилягающие линии?", "Удаление", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                            {
                                Element.seList[i].Delete();
                                Element.seList.Remove(Element.seList[i]);
                                propertyGrid1.Hide();
                            }
                        }
                    }
                }
            }
            else if (e.Button == MouseButtons.Left)
            {
                if (Element.newElement == null)
                {
                    propertyGrid1.Hide();
                    foreach (Element el in Element.seList)
                    {
                        if (el.ClickLeft(MousePos))
                        {
                            Element.sSelEl = el;
                            pOldElDec = el.dec;
                            t.X = pMouseGrid.X - el.dec.X;
                            t.Y = pMouseGrid.Y - el.dec.Y;
                            propertyGrid1.SelectedObject = el;
                            propertyGrid1.Show();
                        }
                    }
                }
            }
        }

        private void b_source_Click(object sender, EventArgs e)
        {
            Element.newElement = new SOURCE();
        }

        private void b_eline_Click(object sender, EventArgs e)
        {
            Element.newElement = new ELine();
        }

        private void b_lamp_Click(object sender, EventArgs e)
        {
            Element.newElement = new LED();
        }

        private void b_or_Click(object sender, EventArgs e)
        {
            Element.newElement = new OR();
        }
        private void b_and_Click(object sender, EventArgs e)
        {
            Element.newElement = new AND();
        }
        private void b_xor_Click(object sender, EventArgs e)
        {
            Element.newElement = new XOR();
        }

        private void b_not_Click(object sender, EventArgs e)
        {
            Element.newElement = new NOT();
        }

        private void b_nand_Click(object sender, EventArgs e)
        {
            Element.newElement = new AND(true);
        }

        private void b_nor_Click(object sender, EventArgs e)
        {
            Element.newElement = new OR(true);
        }

        private void b_nxor_Click(object sender, EventArgs e)
        {
            Element.newElement = new XOR(true);
        }

        private void PanelMain_MouseUp(object sender, MouseEventArgs e)
        {
            if (Element.sSelEl != null)
            {
                if (Element.sSelEl.isPosChage(pOldElDec)) Element.sSelEl.ELineUpdate();
                Element.sSelEl = null;
            }
        }

        private void синийToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ELine.stPen = Pens.Blue;
            ELine.rofrun = false;
        }

        private void зависитОтСигналаToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ELine.rofrun = true;
        }

        private void зелныйToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ELine.stPen = Pens.Green;
            ELine.rofrun = false;
        }

        private void красныйToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ELine.stPen = Pens.Red;
            ELine.rofrun = false;
        }

        private void новыйToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Удалить все элементы?", "Очистка", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
            {
                Element.seList.Clear();
            }
        }

        private void открытьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.DialogResult r = MessageBox.Show("Сохранить схему перед выходом?", "Выход", MessageBoxButtons.YesNoCancel);
            if (r == System.Windows.Forms.DialogResult.No)
            {
                Application.Exit();
            }
            else if (r == System.Windows.Forms.DialogResult.Yes)
            {
                сохранитьToolStripMenuItem_Click(sender, e);
                Application.Exit();
            }
        }

        private void сохранитьToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog sd = new SaveFileDialog();
            sd.Filter = "BLS files|*.bls";
            if (sd.ShowDialog() == DialogResult.OK)
            {
                FileStream fs = new FileStream(sd.FileName, FileMode.Create);
                try
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    formatter.Serialize(fs, Element.seList);
                }
                catch (SerializationException e1)
                {
                    Console.WriteLine("Failed to serialize. Reason: " + e1.Message);
                    throw;
                }
                finally
                {
                    fs.Close();
                }
            }
        }

        private void открытьToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            OpenFileDialog opd = new OpenFileDialog();
            opd.Filter = "BLS files|*.bls";
            if (opd.ShowDialog() == DialogResult.OK)
            {
                FileStream fs = new FileStream(opd.FileName, FileMode.Open);
                try
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    Element.seList = (List<Element>)formatter.Deserialize(fs);
                }
                catch (SerializationException e1)
                {
                    Console.WriteLine("Failed to deserialize. Reason: " + e1.Message);
                    throw;
                }
                finally
                {
                    fs.Close();
                }
            }
        }
      

        private void b_eline_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Up:
                    foreach (Element el in Element.seList)
                    {
                        el.dec.Y -= 10;
                    }
                    break;
                case Keys.Down:
                    foreach (Element el in Element.seList)
                    {
                        el.dec.Y += 10;
                    }
                    break;
                case Keys.Left:
                    foreach (Element el in Element.seList)
                    {
                        el.dec.X -= 10;
                    }
                    break;
                case Keys.Right:
                    foreach (Element el in Element.seList)
                    {
                        el.dec.X += 10;
                    }
                    break;
            }
            switch (e.KeyCode)
            {
                case Keys.Up:
                case Keys.Down:
                case Keys.Left:
                case Keys.Right:
                    foreach (Element el in Element.seList)
                    {
                        el.ELineUpdate();
                    }
                    break;
            }
        }

        private void оПрограммеToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("©FF Group, 2014\nLogic Constructor\nСборка: 26.05.2014 19:39\nПробная версия (осталось 19 дней)", "О программе");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Element.newElement = new ELabel();
        }

    }
    public class DoubleBufferedPanel : Panel
    {
        public DoubleBufferedPanel()
        {
            this.DoubleBuffered = true;
        }
    }

}

